home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
winsock
/
ircii2-6.zip
/
SRC\IRCII-2.6\SOURCE\WINTERM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-09
|
28KB
|
1,234 lines
#include "irc.h"
#include "window.h"
#include "screen.h"
#include "keys.h"
#include "vars.h"
#include <toolhelp.h>
#define TIMER_MINUTE 1
#define TIMER_SECOND 2
extern time_t TimerTimeout();
static HFONT FAR hfontFixed[4];
static COLORREF FAR acrColours[4][2];
static int cxChar;
static int cyChar;
static HWND hwndMain = 0;
static HWND hwndMDI = 0;
static HINSTANCE hInstance = 0;
static WNDPROC old_edit_window_proc = 0;
static fd_set fdsBusy = { 0 };
static fd_set fdsDCC = { 0 };
static fd_set fdsServer = { 0 };
static fd_set fdsDCCWrite = { 0 };
static char *pchPath = 0;
#define WM_SOCKET (WM_USER + 100)
#define AT_USCORE 1
#define AT_BOLD 2
#define AT_INVERSE 4
#define AT_STATUS 8
#define AT_FONTFLAGS 3
#define AT_COLOURFLAGS 12
#define AT_COLOURSHIFT 2
typedef struct TermLineStru
{
char *pchText;
char *pchAttribs;
} TermLine;
char far * far winsock_errors[] =
{
"no error", /* 10000 */
"(Unknown Error)", /* 10001 */
"(Unknown Error)", /* 10002 */
"(Unknown Error)", /* 10003 */
"call cancelled", /* 10004 */
"(Unknown Error)", /* 10005 */
"(Unknown Error)", /* 10006 */
"(Unknown Error)", /* 10007 */
"(Unknown Error)", /* 10008 */
"bad socket number", /* 10009 */
"(Unknown Error)", /* 10010 */
"(Unknown Error)", /* 10011 */
"(Unknown Error)", /* 10012 */
"permission denied", /* 10013 */
"fault in WinSock call", /* 10014 */
"(Unknown Error)", /* 10015 */
"(Unknown Error)", /* 10016 */
"(Unknown Error)", /* 10017 */
"(Unknown Error)", /* 10018 */
"(Unknown Error)", /* 10019 */
"(Unknown Error)", /* 10020 */
"(Unknown Error)", /* 10021 */
"invalid argument to WinSock call", /* 10022 */
"(Unknown Error)", /* 10023 */
"No more sockets", /* 10024 */
"(Unknown Error)", /* 10025 */
"(Unknown Error)", /* 10026 */
"(Unknown Error)", /* 10027 */
"(Unknown Error)", /* 10028 */
"(Unknown Error)", /* 10029 */
"(Unknown Error)", /* 10030 */
"(Unknown Error)", /* 10031 */
"(Unknown Error)", /* 10032 */
"(Unknown Error)", /* 10033 */
"(Unknown Error)", /* 10034 */
"operation would block", /* 10035 */
"blocking operation in progress", /* 10036 */
"already connected", /* 10037 */
"socket operation on non socket", /* 10038 */
"detstination address required", /* 10039 */
"message too long", /* 10040 */
"protocol wrong type for socket", /* 10041 */
"protocol not available", /* 10042 */
"protocol not supported", /* 10043 */
"socket type not supported", /* 10044 */
"operation not supported on a socket", /* 10045 */
"protocol family not supported", /* 10046 */
"address family not supported", /* 10047 */
"address already in use", /* 10048 */
"can't assign requested address", /* 10049 */
"network is down", /* 10050 */
"network is unreachable", /* 10051 */
"network dropped connection on reset", /* 10052 */
"software caused connection abort", /* 10053 */
"connection reset by peer", /* 10054 */
"no buffer space available", /* 10055 */
"socket is already connected", /* 10056 */
"socket is not connected", /* 10057 */
"can't send after socket shutdown", /* 10058 */
"too many references: can't splice", /* 10059 */
"connection timed out", /* 10060 */
"connection refused", /* 10061 */
"too many levels of symbolic links", /* 10062 */
"file name too long", /* 10063 */
"host is down", /* 10064 */
"no route to host", /* 10065 */
"directory not empty", /* 10066 */
"too many processes", /* 10067 */
"too many users", /* 10068 */
"disk quota exceeded", /* 10069 */
"stale NFS file handle", /* 10070 */
"too many levels of remote in path", /* 10071 */
"(Unknown Error)", /* 10072 */
"(Unknown Error)", /* 10073 */
"(Unknown Error)", /* 10074 */
"(Unknown Error)", /* 10075 */
"(Unknown Error)", /* 10076 */
"(Unknown Error)", /* 10077 */
"(Unknown Error)", /* 10078 */
"(Unknown Error)", /* 10079 */
"(Unknown Error)", /* 10080 */
"(Unknown Error)", /* 10081 */
"(Unknown Error)", /* 10082 */
"(Unknown Error)", /* 10083 */
"(Unknown Error)", /* 10084 */
"(Unknown Error)", /* 10085 */
"(Unknown Error)", /* 10086 */
"(Unknown Error)", /* 10087 */
"(Unknown Error)", /* 10088 */
"(Unknown Error)", /* 10089 */
"(Unknown Error)", /* 10090 */
"Windows Sockets not ready", /* 10091 */
"Windows Sockets version not supported", /* 10092 */
"Windows Sockets not initialised", /* 10093 */
"(Unknown Error)", /* 10094 */
"(Unknown Error)", /* 10095 */
"(Unknown Error)", /* 10096 */
"(Unknown Error)", /* 10097 */
"(Unknown Error)", /* 10098 */
"(Unknown Error)", /* 10099 */
};
static int processable_functions[] =
{
FALSE, /* BACKSPACE 0 */
FALSE, /* BACKWARD_CHARACTER 1 */
TRUE, /* BACKWARD_HISTORY 2 */
FALSE, /* BACKWARD_WORD 3 */
FALSE, /* BEGINNING_OF_LINE 4 */
TRUE, /* CLEAR_SCREEN 5 */
FALSE, /* COMMAND_COMPLETION 6 */
FALSE, /* DELETE_CHARACTER 7 */
FALSE, /* DELETE_NEXT_WORD 8 */
FALSE, /* DELETE_PREVIOUS_WORD 9 */
FALSE, /* END_OF_LINE 10 */
FALSE, /* ENTER_DIGRAPH 11 */
FALSE, /* ENTER_MENU 12 */
FALSE, /* ERASE_LINE 13 */
FALSE, /* ERASE_TO_BEG_OF_LINE 14 */
FALSE, /* ERASE_TO_END_OF_LINE 15 */
FALSE, /* FORWARD_CHARACTER 16 */
TRUE, /* FORWARD_HISTORY 17 */
FALSE, /* FORWARD_WORD 18 */
FALSE, /* META1_CHARACTER 19 */
FALSE, /* META2_CHARACTER 20 */
FALSE, /* META3_CHARACTER 21 */
FALSE, /* META4_CHARACTER 22 */
TRUE, /* NEXT_WINDOW 23 */
FALSE, /* NOTHING 24 */
TRUE, /* PARSE_COMMAND 25 */
TRUE, /* PREVIOUS_WINDOW 26 */
FALSE, /* QUIT_IRC 27 */
FALSE, /* QUOTE_CHARACTER 28 */
FALSE, /* REFRESH_INPUTLINE 29 */
FALSE, /* REFRESH_SCREEN 30 */
TRUE, /* SCROLL_BACKWARD 31 */
TRUE, /* SCROLL_END 32 */
TRUE, /* SCROLL_FORWARD 33 */
TRUE, /* SCROLL_START 34 */
FALSE, /* SELF_INSERT 35 */
TRUE, /* SEND_LINE 36 */
FALSE, /* STOP_IRC 37 */
TRUE, /* SWAP_LAST_WINDOW 38 */
TRUE, /* SWAP_NEXT_WINDOW 39 */
TRUE, /* SWAP_PREVIOUS_WINDOW 40 */
TRUE, /* SWITCH_CHANNELS 41 */
FALSE, /* TOGGLE_INSERT_MODE 42 */
FALSE, /* TOGGLE_STOP_SCREEN 43 */
FALSE, /* TRANSPOSE_CHARACTERS 44 */
FALSE, /* TYPE_TEXT 45 */
TRUE, /* UNSTOP_ALL_WINDOWS 46 */
FALSE /* YANK_FROM_CUTBUFFER 47 */
};
typedef struct TermStru
{
int nLines;
int nCols;
TermLine *ptl;
int xPos;
int yPos;
BOOL bResized;
char chAttrib;
int iFlags;
} Term;
#define TF_CTRLDOWN 1
static void set_notifications()
{
int i;
long nTimeout;
FD_ZERO(&fdsServer);
FD_ZERO(&fdsDCC);
FD_ZERO(&fdsDCCWrite);
set_server_bits(&fdsServer);
set_dcc_bits(&fdsDCC, &fdsDCCWrite);
for (i = 0; i < fdsServer.fd_count; i++)
{
WSAAsyncSelect( fdsServer.fd_array[i],
hwndMain,
WM_SOCKET,
FD_READ | FD_CLOSE);
}
for (i = 0; i < fdsDCC.fd_count; i++)
{
WSAAsyncSelect( fdsDCC.fd_array[i],
hwndMain,
WM_SOCKET,
FD_ACCEPT | FD_READ | FD_CLOSE);
}
nTimeout = TimerTimeout();
if (nTimeout <= 60)
SetTimer(hwndMain, TIMER_SECOND, nTimeout * 1000, 0);
while (unhold_windows());
}
static void process_socket(int s, int iEvent, int iError)
{
if (FD_ISSET(s, &fdsBusy))
return;
FD_SET(s, &fdsBusy);
if (FD_ISSET(s, &fdsServer))
{
do_server(&fdsServer);
}
else if (FD_ISSET(s, &fdsDCC))
{
dcc_check(&fdsDCC);
}
FD_CLR(s, &fdsBusy);
set_notifications();
}
static void get_font(void)
{
LOGFONT lf;
HDC hdc;
TEXTMETRIC tm;
HFONT hfontOld;
int i;
hdc = GetDC(GetDesktopWindow());
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
lf.lfHeight = cyChar;
lf.lfWidth = cxChar;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfItalic = 0;
lf.lfStrikeOut = 0;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
strcpy(lf.lfFaceName, "System");
for (i = 0; i < 4; i++)
{
if (i & 2)
lf.lfWeight = FW_BOLD;
else
lf.lfWeight = FW_NORMAL;
if (i & 1)
lf.lfUnderline = 1;
else
lf.lfUnderline = 0;
hfontFixed[i] = CreateFontIndirect(&lf);
}
hfontOld = (HFONT) SelectObject(hdc, (HGDIOBJ) hfontFixed[0]);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
SelectObject(hdc, (HGDIOBJ) hfontOld);
ReleaseDC(GetDesktopWindow(), hdc);
acrColours[0][0] = GetSysColor(COLOR_WINDOWTEXT);
acrColours[0][1] = GetSysColor(COLOR_WINDOW);
acrColours[1][0] = acrColours[0][1];
acrColours[1][1] = acrColours[0][0];
acrColours[2][0] = GetSysColor(COLOR_BTNTEXT);
acrColours[2][1] = GetSysColor(COLOR_BTNFACE);
acrColours[3][0] = GetSysColor(COLOR_CAPTIONTEXT);
acrColours[3][1] = acrColours[2][1];
}
static Term *new_mswindow(void)
{
Term *pt;
pt = (Term *) new_malloc(sizeof(Term));
pt->nLines = pt->nCols = pt->xPos = pt->yPos = 0;
pt->ptl = 0;
pt->chAttrib = 0;
pt->bResized = FALSE;
pt->iFlags = 0;
return pt;
}
static void resize_line(TermLine *ptl, int nOld, int nNew)
{
char *pchText;
char *pchAttribs;
int iSmallest;
if (nOld == nNew)
return;
if (nOld < nNew)
iSmallest = nOld;
else
iSmallest = nNew;
pchText = (char *) new_malloc(nNew);
pchAttribs = (char *) new_malloc(nNew);
memcpy(pchText, ptl->pchText, iSmallest);
memcpy(pchAttribs, ptl->pchAttribs, iSmallest);
memset(pchText + iSmallest, 32, nNew - iSmallest);
memset(pchAttribs + iSmallest, 0, nNew - iSmallest);
new_free(&ptl->pchText);
new_free(&ptl->pchAttribs);
ptl->pchAttribs = pchAttribs;
ptl->pchText = pchText;
}
static void resize_window(Term *pt, int x, int y)
{
TermLine *ptl;
int i;
int iSmallest;
if (y < pt->nLines)
iSmallest = y;
else
iSmallest = pt->nLines;
if (y != pt->nLines)
{
ptl = (TermLine *) new_malloc(sizeof(TermLine) * y);
memcpy(ptl, pt->ptl, sizeof(TermLine) * iSmallest);
memset(ptl + iSmallest, 0, (y - iSmallest) * sizeof(TermLine));
for (i = iSmallest; i < pt->nLines; i++)
{
new_free(&pt->ptl[i].pchText);
new_free(&pt->ptl[i].pchAttribs);
}
new_free(&pt->ptl);
pt->ptl = ptl;
for (i = iSmallest; i < y; i++)
resize_line(pt->ptl + i, 0, x);
}
for (i = 0; i < iSmallest; i++)
resize_line(pt->ptl + i, pt->nCols, x);
pt->nLines = y;
pt->nCols = x;
if (pt->xPos >= pt->nCols)
pt->xPos = pt->nCols - 1;
if (pt->yPos >= pt->nLines)
pt->yPos = pt->nLines - 1;
}
static void char_to_window(Term *pt, char c, HWND hWnd)
{
RECT rcRedraw;
switch(c)
{
case '\r':
pt->xPos = 0;
break;
case '\n':
if (pt->yPos < pt->nLines - 1)
pt->yPos++;
break;
case '\b':
if (pt->xPos > 0)
pt->xPos--;
break;
default:
pt->ptl[pt->yPos].pchText[pt->xPos] = c;
pt->ptl[pt->yPos].pchAttribs[pt->xPos] = pt->chAttrib;
rcRedraw.left = pt->xPos * cxChar;
rcRedraw.right = rcRedraw.left + cxChar;
rcRedraw.top = pt->yPos * cyChar;
rcRedraw.bottom = rcRedraw.top + cyChar;
InvalidateRect(hWnd, &rcRedraw, TRUE);
if (pt->xPos < pt->nCols - 1)
pt->xPos++;
}
}
Term *get_window_info(HWND hWnd)
{
return (Term *) GetWindowLong(hWnd, 0);
}
void output_to_window(char *pchText, int iLen, HWND hwnd)
{
Term *pt;
pt = get_window_info(hwnd);
while (iLen--)
char_to_window(pt, *pchText++, hwnd);
}
static void do_function(HWND hWnd, int iFunc, char *pchArg)
{
Screen *pscrOld, *pscrNew;
char *pchLine;
int iLen;
pscrOld = current_screen;
for (pscrNew = screen_list;
pscrNew->hwnd != GetParent(hWnd);
pscrNew = pscrNew->next);
current_screen = pscrNew;
iLen = GetWindowTextLength(hWnd);
pchLine = (char *) new_malloc(iLen + 1);
GetWindowText(hWnd, pchLine, iLen + 1);
if (iFunc == SEND_LINE)
{
SetWindowText(hWnd, "");
last_input_screen = current_screen;
}
strmcpy(current_screen->input_buffer + current_screen->buffer_min_pos,
pchLine, INPUT_BUFFER_SIZE - current_screen->buffer_min_pos);
current_screen->buffer_pos = strlen(current_screen->input_buffer);
new_free(&pchLine);
key_names[iFunc].func(iFunc, pchArg);
set_current_screen(pscrOld);
set_notifications();
return 0;
}
static int do_character(HWND hWnd, UINT wChar, BOOL bAlt)
{
int iFunc;
char *pchArg;
if (bAlt)
{
iFunc = meta1_keys[wChar].index;
pchArg = meta1_keys[wChar].stuff;
}
else
{
iFunc = keys[wChar].index;
pchArg = keys[wChar].stuff;
}
if (!processable_functions[iFunc])
return 0;
else
{
do_function(hWnd, iFunc, pchArg);
return 1;
}
}
LRESULT CALLBACK _export edit_window_proc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
Term *pt;
if (wMsg == WM_KEYDOWN)
{
pt = get_window_info(GetParent(hWnd));
switch(wParam)
{
case VK_NEXT:
do_function(hWnd, SCROLL_FORWARD, 0);
return 0;
case VK_PRIOR:
do_function(hWnd, SCROLL_BACKWARD, 0);
return 0;
case VK_HOME:
if (pt->iFlags & TF_CTRLDOWN)
{
do_function(hWnd, SCROLL_START, 0);
return 0;
}
break;
case VK_END:
if (pt->iFlags & TF_CTRLDOWN)
{
do_function(hWnd, SCROLL_END, 0);
return 0;
}
break;
case VK_UP:
do_function(hWnd, BACKWARD_HISTORY, 0);
return 0;
case VK_DOWN:
do_function(hWnd, FORWARD_HISTORY, 0);
return 0;
case VK_CONTROL:
pt->iFlags |= TF_CTRLDOWN;
break;
}
}
else if (wMsg == WM_KEYUP && wParam == VK_CONTROL)
{
pt = get_window_info(GetParent(hWnd));
pt->iFlags &= ~TF_CTRLDOWN;
}
else if (wMsg == WM_CHAR)
{
if (lParam & 0x20000000 &&
wParam >= 0 &&
wParam <= 255)
{
if (do_character(hWnd, wParam, TRUE))
return 0;
}
/* Allow binding of control characters other than
* backspace, ^C, ^V, and ^X, plus meta1-anything,
* which becomes ALT-X
*/
if (wParam >= 0 &&
wParam < 32 &&
wParam != 8 &&
wParam != 3 &&
wParam != 24 &&
wParam != 22)
{
if (do_character(hWnd, wParam, FALSE))
return 0;
}
}
return CallWindowProc((FARPROC) old_edit_window_proc, hWnd, wMsg, wParam, lParam);
}
LRESULT CALLBACK _export child_window_proc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
Term *pt;
RECT rcClient;
int i, j;
int xStart, xEnd;
PAINTSTRUCT ps;
char *pchNull;
HWND hwndEdit;
HFONT hfontOld;
char chAttrib;
Screen *pscrOld, *pscrNew;
switch(wMsg)
{
case WM_CREATE:
pt = new_mswindow();
SetWindowLong(hWnd, 0, (LONG) pt);
GetClientRect(hWnd, &rcClient);
hwndEdit = CreateWindow( "EDIT",
"",
WS_CHILD |
WS_HSCROLL |
WS_VISIBLE |
ES_AUTOHSCROLL,
0, rcClient.bottom - cyChar,
rcClient.right, cyChar,
hWnd,
0,
hInstance,
0);
if (!old_edit_window_proc)
old_edit_window_proc = (WNDPROC) GetWindowLong(hwndEdit, GWL_WNDPROC);
SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG) edit_window_proc);
break;
case WM_SIZE:
if (wParam != SIZE_MINIMIZED)
{
pt = get_window_info(hWnd);
GetClientRect(hWnd, &rcClient);
resize_window(pt, rcClient.right / cxChar, rcClient.bottom / cyChar);
MoveWindow(GetDlgItem(hWnd, 0), 0, rcClient.bottom - cyChar,
rcClient.right, cyChar, TRUE);
pscrOld = current_screen;
for (pscrNew = screen_list;
pscrNew && pscrNew->hwnd != hWnd;
pscrNew = pscrNew->next);
if (pscrNew)
{
current_screen = pscrNew;
pt->bResized = TRUE;
refresh_screen();
}
if (pscrOld)
set_current_screen(pscrOld);
else
current_screen = 0;
}
break;
case WM_MDIACTIVATE:
SetFocus(GetDlgItem(hWnd, 0));
break;
case WM_PAINT:
pt = get_window_info(hWnd);
BeginPaint(hWnd, &ps);
hfontOld = (HFONT) SelectObject(ps.hdc, (HGDIOBJ) hfontFixed[0]);
for (i = 0; i < pt->nLines; i++)
{
xStart = 0;
while (xStart < pt->nCols && pt->ptl[i].pchText[xStart])
{
xEnd = xStart;
chAttrib = pt->ptl[i].pchAttribs[xStart];
while (++xEnd < pt->nCols &&
pt->ptl[i].pchText[xEnd] &&
pt->ptl[i].pchAttribs[xEnd] == chAttrib);
SelectObject(ps.hdc, (HGDIOBJ) hfontFixed[chAttrib & AT_FONTFLAGS]);
SetTextColor(ps.hdc, acrColours[(chAttrib & AT_COLOURFLAGS) >> AT_COLOURSHIFT][0]);
SetBkColor(ps.hdc, acrColours[(chAttrib & AT_COLOURFLAGS) >> AT_COLOURSHIFT][1]);
TextOut(ps.hdc, cxChar * xStart, cyChar * i, pt->ptl[i].pchText + xStart, xEnd - xStart);
xStart = xEnd;
}
}
SelectObject(ps.hdc, (HGDIOBJ) hfontOld);
EndPaint(hWnd, &ps);
return 0;
case WM_CLOSE:
pscrOld = current_screen;
for (pscrNew = screen_list;
pscrNew && pscrNew->hwnd != hWnd;
pscrNew = pscrNew->next);
if (pscrNew)
kill_screen(pscrNew);
if (pscrOld)
set_current_screen(pscrOld);
else
current_screen = 0;
break;
}
return DefMDIChildProc(hWnd, wMsg, wParam, lParam);
}
LRESULT CALLBACK _export main_window_proc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT iValue;
switch(wMsg)
{
case WM_SOCKET:
process_socket(wParam,
WSAGETSELECTEVENT(lParam),
WSAGETSELECTERROR(lParam));
return 0;
case WM_SETFOCUS:
iValue = SendMessage(hwndMDI, WM_MDIGETACTIVE, 0, 0L);
SetFocus(GetDlgItem((HWND) LOWORD(iValue), 0));
break;
case WM_CLOSE:
e_quit("QUIT", "Closed main window");
break;
case WM_TIMER:
switch(wParam)
{
case TIMER_MINUTE:
if (get_int_var(CLOCK_VAR))
{
status_update(1);
cursor_to_input();
}
do_notify();
break;
case TIMER_SECOND:
KillTimer(hWnd, TIMER_SECOND);
ExecuteTimers();
break;
}
set_notifications();
break;
case WM_COMMAND:
switch(wParam)
{
case 101:
e_quit("QUIT", "Selected exit option on menu");
break;
case 201:
SendMessage(hwndMDI, WM_MDITILE, MDITILE_VERTICAL, 0);
break;
case 202:
SendMessage(hwndMDI, WM_MDITILE, MDITILE_HORIZONTAL, 0);
break;
case 203:
SendMessage(hwndMDI, WM_MDICASCADE, 0, 0);
break;
case 204:
SendMessage(hwndMDI, WM_MDIICONARRANGE, 0, 0);
break;
}
break;
}
if (hwndMDI)
return DefFrameProc(hWnd, hwndMDI, wMsg, wParam, lParam);
else
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
int PASCAL WinMain(HANDLE hInstance_, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
RECT rcClient;
MSG msg;
CLIENTCREATESTRUCT ccs;
WSADATA wsad;
char *argv[3];
MODULEENTRY me;
TASKENTRY te;
memset(&te, 0, sizeof(te));
te.dwSize = sizeof(te);
TaskFindHandle(&te, GetCurrentTask());
memset(&me, 0, sizeof(me));
me.dwSize = sizeof(me);
ModuleFindHandle(&me, te.hModule);
*strrchr(me.szExePath, '\\') = 0;
malloc_strcpy(&pchPath, me.szExePath);
hInstance = hInstance_;
switch(WSAStartup(0x0101, &wsad))
{
case 0:
if (wsad.wVersion != 0x0101)
{
MessageBox(0, "Your Windows Sockets version is too new", 0, MB_OK);
exit(1);
}
break;
case WSAVERNOTSUPPORTED:
MessageBox(0, "Windows Sockets 1.1 is required", 0, MB_OK);
exit(1);
break;
case WSASYSNOTREADY:
MessageBox(0, "Windows Sockets is not ready", 0, MB_OK);
exit(1);
break;
default:
MessageBox(0, "Could not initialise Windows Sockets", 0, MB_OK);
exit(1);
break;
}
get_font();
memset(&wc, 0, sizeof(wc));
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, "IRC_ICO");
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = COLOR_WINDOW + 1;
wc.lpszClassName = "IRCII Main Window";
wc.lpszMenuName = "MAIN_MNU";
wc.lpfnWndProc = main_window_proc;
RegisterClass(&wc);
wc.lpfnWndProc = child_window_proc;
wc.lpszClassName = "IRCII Child Window";
wc.lpszMenuName = 0;
wc.cbWndExtra = sizeof(void *);
RegisterClass(&wc);
hwndMain = CreateWindow( "IRCII Main Window",
"IRC II for Windows",
WS_OVERLAPPEDWINDOW |
WS_VISIBLE,
CW_USEDEFAULT,
nCmdShow,
CW_USEDEFAULT,
0,
0,
0,
hInstance,
0);
GetClientRect(hwndMain, &rcClient);
ccs.hWindowMenu = GetSubMenu(GetMenu(hwndMain), 1);
ccs.idFirstChild = 1000;
hwndMDI = CreateWindow( "MDICLIENT",
"IRC II MDI Window",
WS_CLIPCHILDREN |
WS_CHILD |
WS_HSCROLL |
WS_VSCROLL |
WS_VISIBLE,
0, 0,
rcClient.right, rcClient.bottom,
hwndMain,
0,
hInstance,
&ccs);
build_status();
argv[0] = "ircii";
argv[1] = lpCmdLine;
argv[2] = 0;
old_main(2, argv);
current_screen = screen_list;
set_notifications();
SetTimer(hwndMain, TIMER_MINUTE, 60000, 0);
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DeleteObject((HGDIOBJ) hfontFixed);
WSACleanup();
}
int
getpid(void)
{
return (int) hInstance;
}
int
getppid(void)
{
return 1;
}
void execcmd(void)
{
yell("EXEC is not available under Windows");
}
void win_create_window(Screen *pscr)
{
MDICREATESTRUCT mdic;
char achNumber[40];
static int nWindow = 0;
mdic.szClass = "IRCII Child Window";
sprintf(achNumber, "Window %d", ++nWindow);
mdic.szTitle = achNumber;
mdic.hOwner = hInstance;
mdic.x = CW_USEDEFAULT;
mdic.y = CW_USEDEFAULT;
mdic.cx = CW_USEDEFAULT;
mdic.cy = CW_USEDEFAULT;
mdic.style = 0;
mdic.lParam = 0;
pscr->hwnd = (HWND) SendMessage(hwndMDI, WM_MDICREATE, 0, (LPARAM) &mdic);
}
void
term_beep(void)
{
MessageBeep(0);
}
void
term_move_cursor(int x, int y)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->xPos = x;
pt->yPos = y;
if (pt->xPos >= pt->nCols)
pt->xPos = pt->nCols - 1;
if (pt->yPos >= pt->nLines)
pt->yPos = pt->nLines - 1;
}
void
term_cr(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->xPos = 0;
}
void
term_newline(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
if (pt->yPos < pt->nLines - 1)
pt->yPos++;
}
int term_scroll(int yStart, int yEnd, int yScroll)
{
Term *pt;
TermLine *ptl;
BOOL bNegative = FALSE;
int i;
RECT rcScroll;
if (yScroll == 0)
return 1;
if (yScroll < 0)
{
bNegative = TRUE;
yScroll = -yScroll;
}
pt = get_window_info(current_screen->hwnd);
if (yStart < 0)
yStart = 0;
if (yEnd >= pt->nLines)
yEnd = pt->nLines - 1;
if (yScroll >= yEnd - yStart + 1)
yScroll = yEnd - yStart + 1;
ptl = (TermLine *) new_malloc(sizeof(TermLine) * yScroll);
if (bNegative)
{
memcpy(ptl, pt->ptl + yEnd + 1 - yScroll, sizeof(TermLine) * yScroll);
memmove(pt->ptl + yStart + yScroll, pt->ptl + yStart, (yEnd - yStart + 1 - yScroll) * sizeof(TermLine));
memcpy(pt->ptl + yStart, ptl, sizeof(TermLine) * yScroll);
for (i = yStart; i < yStart + yScroll; i++)
{
memset(pt->ptl[i].pchText, 32, pt->nCols);
memset(pt->ptl[i].pchAttribs, 0, pt->nCols);
}
}
else
{
memcpy(ptl, pt->ptl + yStart, sizeof(TermLine) * yScroll);
memmove(pt->ptl + yStart, pt->ptl + yStart + yScroll, (yEnd - yStart + 1 - yScroll) * sizeof(TermLine));
memcpy(pt->ptl + yEnd + 1 - yScroll, ptl, sizeof(TermLine) * yScroll);
for (i = yEnd + 1 - yScroll; i <= yEnd; i++)
{
memset(pt->ptl[i].pchText, 32, pt->nCols);
memset(pt->ptl[i].pchAttribs, 0, pt->nCols);
}
}
new_free(&ptl);
GetClientRect(current_screen->hwnd, &rcScroll);
rcScroll.top = cyChar * yStart;
rcScroll.bottom = cyChar * (yEnd + 1);
ScrollWindow(current_screen->hwnd, 0, cyChar * yScroll * (bNegative ? 1 : -1), &rcScroll, &rcScroll);
return 1;
}
#define AT_BOLD 2
#define AT_INVERSE 4
#define AT_STATUS 8
void term_underline_on(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib |= AT_USCORE;
}
void term_underline_off(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib &= ~AT_USCORE;
}
void term_standout_on(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib |= AT_INVERSE;
}
void term_standout_off(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib &= ~AT_INVERSE;
}
void term_bold_on(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib |= AT_BOLD;
}
void term_bold_off(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib &= ~AT_BOLD;
}
void term_status_on(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib |= AT_STATUS;
}
void term_status_off(void)
{
Term *pt;
pt = get_window_info(current_screen->hwnd);
pt->chAttrib &= ~AT_STATUS;
}
int term_clear_screen(void)
{
int i;
Term *pt;
if (!current_screen)
return 0;
pt = get_window_info(current_screen->hwnd);
for (i = 0; i < pt->nLines; i++)
{
memset(pt->ptl[i].pchText, 32, pt->nCols);
memset(pt->ptl[i].pchAttribs, pt->chAttrib, pt->nCols);
}
InvalidateRect(current_screen->hwnd, 0, TRUE);
return 0;
}
int term_clear_to_eol(void)
{
Term *pt;
RECT rcRedraw;
pt = get_window_info(current_screen->hwnd);
memset(pt->ptl[pt->yPos].pchText + pt->xPos, 32, pt->nCols - pt->xPos);
memset(pt->ptl[pt->yPos].pchAttribs + pt->xPos, pt->chAttrib, pt->nCols - pt->xPos);
rcRedraw.top = pt->yPos * cyChar;
rcRedraw.bottom = rcRedraw.top + cyChar;
rcRedraw.left = pt->xPos * cxChar;
rcRedraw.right = pt->nCols * cxChar;
InvalidateRect(current_screen->hwnd, &rcRedraw, TRUE);
return 0;
}
int term_space_erase(int nChars)
{
Term *pt;
RECT rcRedraw;
pt = get_window_info(current_screen->hwnd);
if (nChars > pt->nCols - pt->xPos)
nChars = pt->nCols - pt->xPos;
memset(pt->ptl[pt->yPos].pchText + pt->xPos, 32, nChars);
memset(pt->ptl[pt->yPos].pchAttribs + pt->xPos, pt->chAttrib, nChars);
rcRedraw.top = pt->yPos * cyChar;
rcRedraw.bottom = rcRedraw.top + cyChar;
rcRedraw.left = pt->xPos * cxChar;
rcRedraw.right = pt->nCols * cxChar;
InvalidateRect(current_screen->hwnd, &rcRedraw, TRUE);
return 0;
}
int term_delete(void)
{
Term *pt;
RECT rcScroll;
pt = get_window_info(current_screen->hwnd);
memmove(pt->ptl[pt->yPos].pchText + pt->xPos,
pt->ptl[pt->yPos].pchText + pt->xPos + 1,
pt->nCols = pt->xPos + 1);
memmove(pt->ptl[pt->yPos].pchAttribs + pt->xPos,
pt->ptl[pt->yPos].pchAttribs + pt->xPos + 1,
pt->nCols = pt->xPos + 1);
pt->ptl[pt->yPos].pchText[pt->nCols - 1] = ' ';
pt->ptl[pt->yPos].pchAttribs[pt->nCols - 1] = pt->chAttrib;
rcScroll.top = pt->yPos * cyChar;
rcScroll.bottom = rcScroll.top + cyChar;
rcScroll.left = pt->xPos * cxChar;
rcScroll.right = pt->nCols * cxChar;
ScrollWindow(current_screen->hwnd, -cxChar, cyChar, &rcScroll, &rcScroll);
return 0;
}
int term_get_columns(void)
{
Term *pt;
RECT rcRedraw;
if (!current_screen)
return 80;
pt = get_window_info(current_screen->hwnd);
return pt->nCols;
}
int term_get_rows(void)
{
Term *pt;
RECT rcRedraw;
if (!current_screen)
return 80;
pt = get_window_info(current_screen->hwnd);
return pt->nLines;
}
int term_flush(void)
{
UpdateWindow(current_screen->hwnd);
}
int term_resize(void)
{
Term *pt;
RECT rcRedraw;
BOOL bResized;
if (!current_screen)
return 0;
pt = get_window_info(current_screen->hwnd);
bResized = pt->bResized;
pt->bResized = 0;
return bResized;
}
void
set_input(str)
char *str;
{
Term *pt;
int iLen;
pt = get_window_info(current_screen->hwnd);
SetWindowText(GetDlgItem(current_screen->hwnd, 0), str);
iLen = strlen(str);
SendMessage(GetDlgItem(current_screen->hwnd, 0), EM_SETSEL, 0,
MAKELPARAM(iLen, iLen));
}
char *
get_input()
{
return (&(current_screen->input_buffer[current_screen->buffer_min_pos]));
}
char *
get_path(int iVal)
{
static char FAR buffer[BIG_BUFFER_SIZE];
strcpy(buffer, pchPath);
switch(iVal)
{
case 0: /* Irc Lib (with trailing slash) */
strcat(buffer, "/LIB/");
break;
case 1: /* Help Path */
strcat(buffer, "/HELP");
break;
case 2: /* Translation Path */
strcat(buffer, "/TRANSLAT");
break;
case 3: /* Load Path */
strcat(buffer, "/SCRIPTS");
break;
case 4: /* IRC directory */
break;
}
return buffer;
}